package com.juzhencms.apps.busi.service;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.Feature;

import com.juzhencms.apps.base.common.config.Config;
import com.juzhencms.apps.base.common.database.DBTable;
import com.juzhencms.apps.base.common.util.ObjectUtil;

import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class AdminMenuService extends CommonService{
	
	//存储权限配置文件中的json数据
	private LinkedHashMap permissionsData;
	//存储各模块对应的权限map,只有一级，以模块名为key值，权限内容包括各控制器及对应的方法
	private Map modulesAction;
	
	/**
	 * 获取权限配置文件中的内容
	 * @return
	 */
	public Map getPermissionsData() {
		// TODO Auto-generated method stub
		
		if(permissionsData==null){
			InputStream in;
			try {
				
				
				InputStream stream = getClass().getClassLoader().getResourceAsStream("adminPermissions.json");
				BufferedReader r = new BufferedReader(new InputStreamReader(stream, "UTF-8")); 
				//BufferedReader r = new BufferedReader(new InputStreamReader(new FileInputStream(ResourceUtils.getFile("classpath:config/adminPermissions.json")), "UTF-8")); 
				
				
				
				StringBuffer buffer = new StringBuffer();
				String line = " ";
				try {
					while ((line = r.readLine()) != null){
					     buffer.append(line);
					}
				} catch (IOException e) {
					// TODO Auto-generated catch block
					log.error("读取adminPermissions.json出错",e);
				}
				
				permissionsData=JSON.parseObject(buffer.toString(),LinkedHashMap.class,Feature.OrderedField);
				
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				log.error("adminPermissions.json解析出错",e);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				log.error("adminPermissions.json读取出错",e);
			}
		}
		//return ObjectUtil.copy(permissionsData, Map.class);
		return permissionsData;
	}
	
	
	
	/**
	 * 获取各模块的权限数据，一级map,以模块名为key值
	 * @return
	 */
	public Map getModulesAction(){
		if(modulesAction==null){
			modulesAction=new HashMap();
			Map permissionsData=this.getPermissionsData();
			
			//获取功能模块数据
			Map<String, Map>modulePermissions=(Map<String, Map>) permissionsData.get("modulePermissions");
			for(Map.Entry<String, Map> entry : modulePermissions.entrySet()) {
			   Map module=entry.getValue();
			   if(module.get("sub")!=null)
				   this.makeModulesAction((List)module.get("sub"), modulesAction);
			   
			}
			//获取栏目模块数据
			Map<String, Map> menuModulePermissions=(Map<String, Map>)permissionsData.get("menuModulePermissions");
			for(Map.Entry<String, Map> entry : menuModulePermissions.entrySet()) {
			   Map module=entry.getValue();
			   if(module.get("actions")!=null){
				   modulesAction.put(entry.getKey(),module.get("actions"));
			   }
			   if(module.get("options")!=null){
					List options=(List)module.get("options");
					for(int j=0;j<options.size();j++){
						Map option=(Map)options.get(j);
						String moduleName=entry.getKey()+"."+option.get("option");
						modulesAction.put(moduleName, option.get("actions"));
					}
			   }
			}
		}
		//return ObjectUtil.copy(modulesAction, Map.class);
		return modulesAction;
	}
	
	private void makeModulesAction(List permissionsList,Map result){
		if(permissionsList!=null)
			for(int i=0;i<permissionsList.size();i++){
				Map module=(Map)permissionsList.get(i);
				
				if(module.get("module")!=null && module.get("actions")!=null){
					result.put(module.get("module"), module.get("actions"));
				}
				if(module.get("sub")!=null){
					this.makeModulesAction((List)module.get("sub"), result);
				}
				if(module.get("options")!=null){
					List options=(List)module.get("options");
					for(int j=0;j<options.size();j++){
						Map option=(Map)options.get(j);
						String moduleName=module.get("module").toString()+"."+option.get("option");
						result.put(moduleName, option.get("actions"));
					}
				}	
			}
	}
	
	
	//获取模块的连接参数
	private Map getAdminMenuLink(Map menuData){
		if(menuData.get("module")!=null && !menuData.get("module").equals("")){
			Map link=new HashMap();
			link.put("type", "state");
			link.put("name", menuData.get("module"));
			Map linkParam=new HashMap();
			linkParam.put("menu", menuData.get("id"));
			link.put("param",linkParam);
			return link;
		}else{
			return null;
		}
	}
	
	//根据数据库的栏目数据对应的权限数组
	private Map getMenuPermissions(Map menuData){
		if(menuData.get("module")!=null){
			Map permissionsData=this.getPermissionsData();
			Map menuModulePermissions=(Map)permissionsData.get("menuModulePermissions");
			if(menuModulePermissions.get(menuData.get("module").toString())!=null){
				return ObjectUtil.copy((Map)((Map)menuModulePermissions.get(menuData.get("module").toString())),Map.class);
			}else{
				return null;
			}
		}else{
			return null;
		}
	}

	
	//@Cacheable(value="dbCache",key="#root.target+'.'+#root.method")
	public List getAllSiteMenuTreeList() {
		//LogTool.info("no cache", this.getClass());
		List siteList=this.getJdbcDao().querySql("select id,name as text,case when (domain_protocol='http://' and domain_port='80') or (domain_protocol='https://' and domain_port='443') or domain_port is null or domain_port='' then concat(domain_protocol,domain,domain_path) else concat(domain_protocol,domain,':',domain_port,domain_path) end as domain,publish from "+DBTable.site+" where del_flag=0 order by position asc,create_time asc");
		
		//List siteList=this.getJdbcDao().querySql("select id,name as text from "+DBTable.site+" where del_flag=0 order by position asc,create_time asc");
		
		if(siteList!=null && siteList.size()>0){
			for(int i=0;i<siteList.size();i++){
				Map site=(Map)siteList.get(i);
				site.put("module", "site_"+site.get("id"));
				List tmp=this.getSiteMenuTreeList(new Integer(site.get("id").toString()));
				if(tmp!=null)
					site.put("sub", tmp);
			}
			return siteList;
		}else{
			return null;
		}
	}
	
	public List getSiteMenuTreeList(String siteIds) {
		//LogTool.info("no cache", this.getClass());
		
		List siteList=this.getJdbcDao().querySql("select id,name as text,case when (domain_protocol='http://' and domain_port='80') or (domain_protocol='https://' and domain_port='443') or domain_port is null or domain_port='' then concat(domain_protocol,domain,domain_path) else concat(domain_protocol,domain,':',domain_port,domain_path) end as domain,publish from "+DBTable.site+" where del_flag=0 and id in("+siteIds+") order by position asc,create_time asc");
		if(siteList!=null && siteList.size()>0){
			for(int i=0;i<siteList.size();i++){
				Map site=(Map)siteList.get(i);
				site.put("module", "site_"+site.get("id"));
				List tmp=this.getSiteMenuTreeList(new Integer(site.get("id").toString()));
				if(tmp!=null)
					site.put("sub", tmp);
			}
			return siteList;
		}else{
			return null;
		}
	}
	
	public List getSiteMenuTreeList(int siteId) {
		
		//查询有下级栏目的栏目清单
		List parentsList=this.getJdbcDao().querySql("select distinct parent_id from "+DBTable.menu+" where site_id=? and del_flag=0 ", new Object[]{siteId});
		Map parentsIdMap=new HashMap();
		if(parentsList!=null) {
			for(int i=0;i<parentsList.size();i++) {
				Map row=(Map)parentsList.get(i);
				parentsIdMap.put(row.get("parent_id").toString(), 1);
			}
		}
		
		
		List menuList=this.getJdbcDao().querySql("select id,name as text,module from "+DBTable.menu+" where site_id=? and parent_id=0 and del_flag=0 order by position asc,create_time asc", new Object[]{siteId});
		if(menuList!=null && menuList.size()>0){
			
			for(int i=0;i<menuList.size();i++){
				Map row=(Map)menuList.get(i);
				row.put("link", this.getAdminMenuLink(row));
				Map permissions=this.getMenuPermissions(row);
				if(permissions!=null) {
					row.put("actions", (Map)permissions.get("actions"));
					row.put("options", (List)permissions.get("options"));
				}
				
				if(parentsIdMap.get(row.get("id").toString())!=null) {
					List tmp=this.getSubMenuTreeList(new Integer(row.get("id").toString()),parentsIdMap);
					if(tmp!=null)
						row.put("sub", tmp);
				}

				
				
				String key=row.get("id").toString();
				if(row.get("module")!=null && !row.get("module").toString().equals("")){
					key+="."+row.get("module");
				}
				row.put("module", key);
			}
			
			return menuList;
		}else{
			return null;
		}
	}
	
	@SuppressWarnings("all")
	public List getSubMenuTreeList(int pid,Map parentsIdMap){
		// TODO Auto-generated method stub
		
		List menuList=this.getJdbcDao().querySql("select id,name as text,module from "+DBTable.menu+" where parent_id=? and del_flag=0 order by position asc,create_time asc", new Object[]{pid});
		if(menuList!=null && menuList.size()>0){
			
			for(int i=0;i<menuList.size();i++){
				Map row=(Map)menuList.get(i);
				row.put("link", this.getAdminMenuLink(row));
				Map permissions=this.getMenuPermissions(row);
				if(permissions!=null) {
					row.put("actions", (Map)permissions.get("actions"));
					row.put("options", (List)permissions.get("options"));
				}	

				List tmp=this.getSubMenuTreeList(new Integer(row.get("id").toString()),parentsIdMap);
				if(tmp!=null)
					row.put("sub", tmp);
				
				String key=row.get("id").toString();
				if(row.get("module")!=null && !row.get("module").toString().equals("")){
					key+="."+row.get("module");
				}
				row.put("module", key);
			}
			
			return menuList;
		}else{
			return null;
		}
	}


	
	
}
